package com.dji.ux.sample.MediaManager;

import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.util.Log;

import androidx.annotation.RequiresApi;

import com.dji.ux.sample.CompleteWidgetActivity;
import com.dji.ux.sample.DJISampleApplication;
import com.dji.ux.sample.ModuleVerificationUtil;
import com.dji.ux.sample.Utils.SpUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import Decoder.BASE64Encoder;
import dji.common.camera.SettingsDefinitions;
import dji.common.error.DJIError;
import dji.common.util.CommonCallbacks;
import dji.sdk.media.DownloadListener;
import dji.sdk.media.MediaFile;
import dji.sdk.media.MediaManager;

public class MediaUtil {

    private static MediaManager mediaManager;
    private static MediaFile media;
    private static List<byte[]> jpgBytes = new ArrayList<>();
    private static List<MediaFile> jpgMedias = new ArrayList<>();
    private static String TAG = "MediaUtil";
    private static List<String> nodeIDs = new ArrayList<>();
    private static Context mcontext;
    private static MediaEventCallBack mediaEventCallBack;
    private static MediaEvent mediaEvent = new MediaEvent();

    public interface MediaEventCallBack {
        void onEventStart();

        void onEventUpdate(MediaEvent mediaEventState);

        void onEventSuccess(String id, String pic_path);

        void onEventFailure(String error);
    }


    private static void setupMediaManager() {
        if (ModuleVerificationUtil.isCameraModuleAvailable()) {
            if (mediaManager == null) {
                mediaManager = DJISampleApplication.getProductInstance().getCamera().getMediaManager();
            }

            DJISampleApplication.getProductInstance()
                    .getCamera()
                    .setMode(SettingsDefinitions.CameraMode.MEDIA_DOWNLOAD,
                            djiError -> {
                                if (null == djiError) {
                                    fetchMediaList();
                                }
                            });
        } else {
            Log.e(TAG, "setupMediaManager failed, CameraModule not Available");
        }
    }

    public static void setMediaUpdateListener(Context context, MediaEventCallBack CallBack) {
        Log.d(TAG, "setMediaUpdateListener");
        mcontext = context;
        mediaEventCallBack = CallBack;
        if (ModuleVerificationUtil.isCameraModuleAvailable()) {
            DJISampleApplication.getProductInstance()
                    .getCamera()
                    .setMediaFileCallback(mediaFile -> {
//                        if (CompleteWidgetActivity.needupload) {
                        Log.d(TAG, "MediaFile update: " + mediaFile.getFileName() + mediaFile.getFileSize());
                        try {
                            Thread.sleep(1000);
                            setupMediaManager();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

//                        }
                    });
        }
    }

    public static void resetCamera() {
        new Thread(() -> {
            if (ModuleVerificationUtil.isCameraModuleAvailable()) {
                DJISampleApplication.getProductInstance()
                        .getCamera()
                        .setMode(SettingsDefinitions.CameraMode.SHOOT_PHOTO,
                                djiError -> {
                                    if (djiError != null)
                                        Log.d(TAG, "*************** resetCamera: ");
                                });
            }
        }).start();

    }

    // Initialize the view with getting a media file.
    private static void fetchMediaList() {
        if (ModuleVerificationUtil.isMediaManagerAvailable()) {
            if (mediaManager != null) {
                mediaManager.refreshFileListOfStorageLocation(SettingsDefinitions.StorageLocation.SDCARD, new CommonCallbacks.CompletionCallback() {
                    @Override
                    public void onResult(DJIError djiError) {
                        if (null == djiError) {
                            List<MediaFile> djiMedias = mediaManager.getSDCardFileListSnapshot();
                            jpgMedias.clear();
                            if (djiMedias != null) {
                                for (MediaFile mediaFile : djiMedias) {
                                    Log.d(TAG, "filename: " + mediaFile.getFileName());
                                    //判断文件名后缀是否为jpg，并插入jpgMedias列表
                                    if (mediaFile.getFileName().substring(mediaFile.getFileName().indexOf(".") + 1).equals("jpg")) {
                                        jpgMedias.add(mediaFile);
                                    }
                                }
                            }
                            downloadMedia(1);
                        } else {
                            Log.e(TAG, djiError.getDescription());
                        }
                    }
                });
            }
        }
    }

    private static void downloadMedia(int downloadCount) {
        // Download Media Byte Data
        if (ModuleVerificationUtil.isCameraModuleAvailable()
                && mediaManager != null) {
            String str;
            if (!jpgMedias.isEmpty()) {
                for (int i = 0; i < downloadCount; i++) {
                    //获取列表末端的下标
                    int downloadIndex = jpgMedias.size() - (1 + i);
                    media = jpgMedias.get(downloadIndex);
                    str = "Total Media files:" + jpgMedias.size() + " Media : " + i + jpgMedias.get(downloadIndex).getFileName();
//                    Log.d(TAG, str);
                    downloadMediaByteData(media);
                }
            } else {
                str = "No Media in SD Card";
                Log.e(TAG, str);
            }
        } else {
            Log.d(TAG, "downloadMedia: CameraModule not Available");
        }
    }

    private static void downloadMediaByteData(MediaFile media) {
        media.fetchFileByteData(0, new DownloadListener<String>() {

            @Override
            public void onStart() {
                Log.d(TAG, "onStart:");
                jpgBytes.clear();
                mediaEvent.setDownloadState(MediaEvent.DOWNLOAD_STATUS.ON_START);
                mediaEventCallBack.onEventStart();
            }

            @Override
            public void onRateUpdate(long total, long current, long persize) {
                Log.d(TAG, String.format("onRateUpdate: total = %d, current = %d, persize = %d", total, current, persize));
            }

            @Override
            public void onProgress(long total, long current) {
                Log.d(TAG, String.format("onProgress: total = %d, current = %d", total, current));
                mediaEvent.setDownloadState(MediaEvent.DOWNLOAD_STATUS.DOWNLOADING);
                mediaEvent.setProgress((int) (Math.round(current * 1.0f / total * 100f) / 100f * 100f));
                mediaEventCallBack.onEventUpdate(mediaEvent);
            }

            /**
             * 下载成功后，拼接多段字节数组，并进行base64编码
             * @param savePath
             */
            @RequiresApi(api = Build.VERSION_CODES.N)
            @Override
            public void onSuccess(String savePath) {
                int length_byte = 0;
                for (int i = 0; i < jpgBytes.size(); i++) {
                    length_byte += jpgBytes.get(i).length;
                }
                byte[] all_byte = new byte[length_byte];
                int countLength = 0;
                //拼接图片字节数组
                for (int i = 0; i < jpgBytes.size(); i++) {
                    byte[] b = jpgBytes.get(i);
                    System.arraycopy(b, 0, all_byte, countLength, b.length);
                    countLength += b.length;
                }
                //base64编码
                String strAllByte = new BASE64Encoder().encode(all_byte);
                try {
                    File dirFolder = new File(Environment.getExternalStorageDirectory().getPath() + "/Dji_Sdk_Test");//方法二：通过变量文件来获取需要创建的文件夹名字
                    if (!dirFolder.exists()) {
                        boolean mkdirs = dirFolder.mkdirs();
                    }
                    String curID = nodeIDs.get(CompleteWidgetActivity.waypointcount);
                    String output = Environment.getExternalStorageDirectory().
                            getPath() + String.format("/Dji_Sdk_Test/%s.jpg", curID);
                    Map<Object, Object> map = SpUtils.getMap("uploadMap");
                    map.replace(curID, output);
                    SpUtils.setMap(mcontext, "uploadMap", map);
                    Log.d(TAG, "setMap: " + map.toString());
                    mediaEventCallBack.onEventSuccess(curID, output);

                    DecodeBase64IMG.decoderBase64File(strAllByte, output);
                    Log.d(TAG, "The file has been stored, its path is " + output);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                resetCamera();
                MediaUploadUtil.uploadJPG(strAllByte);
            }

            @Override
            public void onFailure(DJIError djiError) {
                mediaEventCallBack.onEventFailure(djiError.getDescription());
                Log.e(TAG, "onFailure: " + djiError.getDescription());
            }

            /**
             * 分段下载字节数组
             * @param bytes
             * @param l
             * @param b
             */
            @Override
            public void onRealtimeDataUpdate(byte[] bytes, long l, boolean b) {
                //encode image ByteArray to Base64 string
//                Log.d(TAG, String.format("onRealtimeDataUpdate: position = %d, isLastPack = %b, size = %d", l, b, bytes.length));
                jpgBytes.add(bytes);
            }
        });
    }

    public static void setNodeIDs(List<String> nodes) {
        nodeIDs = nodes;
    }

}
